import { _decorator, Component, Node, Prefab, instantiate } from 'cc';
import GlobalData from '../Config/GlobalData';
import { GlobalEnum } from '../Config/GlobalEnum';
import EventManager from '../Managers/EventManager';
import { EventTypes } from '../Managers/EventTypes';
import { StorageSystem } from '../SystemStorage/StorageSystem';
import { UIEnum } from '../SystemUI/UIEnum';
import { UISystem } from '../SystemUI/UISystem';
import { clog } from '../Tools/ColorLog';
import GlobalPool from '../Tools/GlobalPool';
import Loader from '../Tools/Loader';
const { ccclass, property } = _decorator;
/**
 * 控制整个游戏的流程
 */
@ccclass('GameDirector')
export class GameDirector extends Component {
    private _levelManager: Node = null;
    private _isOver = false;
    // #region --------------------生命周期--------------------
    protected onLoad() {
        this.onEvents();
    }

    protected onEvents() {
        EventManager.on(EventTypes.GameEvents.GameStart, this.onGameStart, this);
        EventManager.on(EventTypes.GameEvents.GameOver, this.onGameOver, this);
        EventManager.on(EventTypes.GameEvents.SetLevelManagerEnable, this.onSetLevelManagerEnable, this);
        EventManager.on(EventTypes.GameEvents.SetTouchMaskEnable, this.onSetTouchMaskEnable, this);
    }

    // #endregion

    // #region ---------------------私有方法--------------------

    /**必须加载的额外子包 */
    private subPackgeArr = [];
    /**记录加载状态 */
    private subPackgeRec: { [bound: string]: boolean } = {};
    /**加载必要的子包 */
    protected loadSubBound(cb) {
        if (this.subPackgeArr.length == 0) {
            cb && cb();
            return;
        }

        let loadFinishCb = (boundName: string) => {
            this.subPackgeRec[boundName] = true;
            // 检测是否加载完毕
            let isFinished = true;
            for (const key in this.subPackgeRec) {
                isFinished = isFinished && this.subPackgeRec[key];
            }
            if (isFinished) {
                cb && cb();
            }
        }
        for (let i = 0, c = this.subPackgeArr.length; i < c; ++i) {
            const boundName = this.subPackgeArr[i];
            if (undefined === this.subPackgeRec[boundName]) {
                this.subPackgeRec[boundName] = false;
            }
            if (!this.subPackgeRec[boundName]) {
                Loader.loadBundle(this.subPackgeArr[i], () => {
                    loadFinishCb(boundName);
                }, true, false);
            } else {
                loadFinishCb(boundName);
            }
        }
    }

    //记录加载状态
    private isLoadFinish = false;
    //加载游戏中必要的资源
    private loadGameAssets(cb) {
        if (this.isLoadFinish) {
            this.delayLoadPrefabs(cb);
        } else {

            //先加载自定义资源-第一次
            this.loadCustomPrefabs(() => {
                //在加载必须的资源
                this.loadLevelPrefab(() => {
                    if (!this.isLoadFinish) {
                        this.isLoadFinish = true;
                        clog.log('游戏中预制体加载完成');
                        cb && cb();
                    }
                })

            })

        }
    }

    /**游戏资源包名 */
    private levelBound = 'Game';
    /**游戏必须加载的预制体路径 */
    private singlePrefabUrl = 'Perfabs/Common/LevelManager';
    /**加载关卡必须的预制体 */
    private loadLevelPrefab(cb) {

        Loader.loadBundle(this.levelBound, () => {
            Loader.loadBundleRes(this.levelBound, this.singlePrefabUrl, (prefab: Prefab) => {

                let node = instantiate(prefab);
                node.parent = this.node;
                this._levelManager = node;
                cb && cb();
            }, Prefab, false);
        }, true);

    }

    /**游戏自定义的预制体路径,bound : url */
    private customPrefabUrl: { [bound: string]: string } = {
        'Game': 'Perfabs/Custom',
        'Level1': 'props',
        'Effect': 'gameEffects',
        'LevelModels': 'prefabs',
        'LevelRoles': 'prefabs',
    };
    private isDelayLoadFinished = false;
    //非第一关必要的资源
    private delayPrefabelUrl: { [bound: string]: string } = {
        'LevelModels': 'prefabs',
    }
    //加载非第一关的资源
    private delayLoadPrefabs(cb) {
        if (!this.isDelayLoadFinished && StorageSystem.getData().levelAssets.curLv > 1) {
            let d: { [bound: string]: { isLoadPrefab: boolean, prefabUrl: string, isMask: boolean } } = {};
            //
            for (const key in this.delayPrefabelUrl) {
                d[key] = { isLoadPrefab: true, prefabUrl: this.delayPrefabelUrl[key], isMask: true };
            }
            this.onLoadSubPkg(d, () => {
                this.isDelayLoadFinished = true;
                cb && cb();
            });
        } else {
            cb && cb();
        }
    }

    /**自定义预制加载状态记录 */
    private customPrefabState: { [bound: string]: boolean } = {};

    /**加载关卡自定义的预制体 并创建对象池 */
    private loadCustomPrefabs(cb) {
        let loadPerfabFinish = (boundName: string) => {
            this.customPrefabState[boundName] = true;
            // 检测是否加载完毕
            let isFinished = true;
            for (const key in this.customPrefabState) {
                isFinished = isFinished && this.customPrefabState[key];
            }
            if (isFinished) {
                //非第一关的资源
                this.delayLoadPrefabs(cb);
            }
        }

        for (const bound in this.customPrefabUrl) {

            if (undefined == this.customPrefabState[bound]) {
                this.customPrefabState[bound] = false;
            }
            if (!this.customPrefabState[bound]) {
                const url = this.customPrefabUrl[bound];
                Loader.loadBundle(bound, () => {
                    Loader.loadBundleDir(bound, url, (prefabs: Prefab[]) => {
                        for (let i = 0; i < prefabs.length; i++) {
                            const p = prefabs[i];
                            GlobalPool.createPool(p.data.name, p);
                        }
                        loadPerfabFinish(bound);
                    }, Prefab, false);
                }, true);
            } else {
                loadPerfabFinish(bound);
            }

        }
    }

    private _tmpLoadState: { [bound: string]: boolean } = {};
    /**动态加载指定的分包资源 并实例化预制体-创建对象池*/
    protected onLoadSubPkg(data: { [bound: string]: { isLoadPrefab: boolean, prefabUrl: string, isMask: boolean } }, cb) {
        //初始化状态
        this._tmpLoadState = {};
        for (const bound in data) {
            const d = data[bound];
            this._tmpLoadState[bound] = false;
            const isMask = d.isMask || false;
            console.log('#1 动态加载分包开始:', bound);

            Loader.loadBundle(bound, () => {
                //加载预制体-创建对象池
                if (d.isLoadPrefab) {
                    const url = d.prefabUrl || '';
                    Loader.loadBundleDir(bound, url, (prefabs: Prefab[]) => {
                        for (let i = 0; i < prefabs.length; i++) {
                            const p = prefabs[i];
                            GlobalPool.createPool(p.data.name, p);
                        }
                        this.loadDealyPerfabFinish(bound, cb);
                    }, Prefab, isMask);
                } else {
                    this.loadDealyPerfabFinish(bound, cb);
                }
            }, isMask);
        }
    }


    private loadDealyPerfabFinish = (boundName: string, cb) => {
        this._tmpLoadState[boundName] = true;
        // 检测是否加载完毕
        let isFinished = true;
        for (const key in this._tmpLoadState) {
            isFinished = isFinished && this._tmpLoadState[key];
        }
        console.log('#2 动态加载分包:', boundName, '完成');
        if (isFinished) {
            cb && cb();
        }
    }

    // #endregion

    // #region ---------------------事件回调--------------------
    /**控制touchMask显隐 */
    private _touchMask: Node = null;
    protected onSetTouchMaskEnable(isEnable = false) {
        if (!this._touchMask) {
            let cvs = GlobalData.get(GlobalEnum.GlobalDataType.Canvas) as Node;
            this._touchMask = cvs.getChildByName('TouchMask');
        }
        this._touchMask.active = isEnable;
        clog.warn('TouchMask: ' + isEnable);
    }

    /**控制游戏内容显隐 */
    protected onSetLevelManagerEnable(isEnable) {
        if (undefined == isEnable || !this._levelManager) return;
        this._levelManager.active = isEnable;
    }

    /**开始游戏 */
    protected onGameStart(cb?) {
        //
        EventManager.emit(EventTypes.GameEvents.SetInitUIEnable, true);
        this._isOver = false;

        //加载游戏必须的其他子包
        this.loadSubBound(() => {
            //加载关卡必须的预制体
            this.loadGameAssets(() => {
                //激活游戏内容
                this._levelManager.active = true;
                //关闭initUI
                EventManager.emit(EventTypes.GameEvents.SetInitUIEnable, false);
                //回调
                cb && cb();
            })
        })
    }

    /**游戏结束 */
    private onGameOver(isWin) {
        if (this._isOver) return;
        this._isOver = true;
        let data = StorageSystem.getData();
        let isShowBoxUI = data.levelAssets.curLv > 1 && data.userAssets.keyNum >= 3;

        UISystem.hideUI(UIEnum.LevelController);
        if (isWin) {
            if (isShowBoxUI) {
                UISystem.showUI(UIEnum.FinishAwardBoxUI, true);
            } else {
                UISystem.showUI(UIEnum.WinUI);
            }
            //关卡+1
            StorageSystem.addLv();
        } else {
            if (isShowBoxUI) {
                UISystem.showUI(UIEnum.FinishAwardBoxUI, false);
            } else {
                UISystem.showUI(UIEnum.LoseUI);
            }
        }
    }
    // #endregion

}

